package com.itheima.spring;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SpringApplicationContext {
    //定义一个map集合作为IOC容器
    private Map<String, Object> map = new HashMap<String, Object>();

    //构造函数传递需要解析的配置文件名称
    public SpringApplicationContext(String xmlName){
        //调用方法解析配置文件
        map = analysisXml(xmlName);
    }

    //解析beans.xml核心配置文件并存入map集合中
    private Map<String, Object> analysisXml(String xmlName){
        try {
            //创建dom4j对象
            SAXReader saxReader = new SAXReader();
            InputStream is = SpringApplicationContext.class.getClassLoader().getResourceAsStream(xmlName);
            //读取配置文件
            Document read = saxReader.read(is);
            Element rootElement = read.getRootElement();
            //获取配置文件下的所有bean标签
            List<Element> beans = rootElement.elements("bean");
            if (beans!=null && beans.size()>0){
                for (Element bean : beans) {
                    //获取每个bean标签的属性name和value
                    String id = bean.attributeValue("id");
                    String path = bean.attributeValue("class");
                    //看看该对象是否已经存在
                    Object o = map.get(id);
                    //如果不存在就创建对象存入集合
                    if (o==null){
                        //使用反射创建对象
                        Class<?> clazz = Class.forName(path);
                        Object obj = clazz.newInstance();
                        //将name和对象存入map集合
                        map.put(id,obj);

                        //依赖注入
                        //获取配置文件下的所有property标签
                        List<Element> properties = bean.elements("property");
                        for (Element property : properties) {
                            //  name="username"
                            String name = property.attributeValue("name");
                            String value = property.attributeValue("value");
                            //将获取的name属性值变为setName
                            //获取第一个字母变大写 u--> U
                            char c1 = Character.toUpperCase(name.charAt(0));
                            //切割然后拼接    username>---sername
                            name = name.substring(1);
                            //set + U +sername ==>setUsername
                            name="set"+c1+name;
                            //使用反射获取方法setName并设置对应值
                            Method method = clazz.getMethod(name, String.class);
                            method.invoke(obj,value);
                        }
                    }
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    //获取接口实现类对象  并返回
    public Object getBean(String id){
        Object o = map.get(id);
        return o;
    }

}
